﻿using Framework.Core.Attributes;
using Framework.Core.Enums;
using Framework.SqlSugarCore.Repositories;
using Microsoft.AspNetCore.Mvc;
using my.abp.Domain.IManagers.Dict;
using my.abp.Domain.Repositories.Dict;
using my.abp.Domain.Shared.Entities;
using my.abp.Domain.Shared.Enums;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services;

namespace my.abp.Domain.Managers.Dict
{
	public class SysDictTypeManager : DomainService, ISysDictTypeManager
	{
		private readonly ISysDictTypeRepository _sysDictTypeRepository;
		private readonly ISysDictDataManager _sysDictDataManager;
		public SysDictTypeManager(ISysDictTypeRepository sysDictTypeRepository, ISysDictDataManager sysDictDataManager)
		{
			_sysDictTypeRepository = sysDictTypeRepository;
			_sysDictDataManager = sysDictDataManager;
		}

		public async Task<List<SysDictData>> GetDataList(string code)
		{
			var queryable = await _sysDictTypeRepository.AsQueryable();
			return await queryable.LeftJoin<SysDictData>((u, a) => u.Id == a.DictTypeId)
				.Where((u, a) => u.Code == code && u.Status == StatusEnum.Enable && a.Status == StatusEnum.Enable)
				.OrderBy((u, a) => new { a.OrderNo, a.Code })
				.Select((u, a) => a).ToListAsync();
		}

		public async Task<List<SysDictData>> GetDataList(string code, int? Status)
		{
			var queryable = await _sysDictTypeRepository.AsQueryable();
			return await queryable
				.LeftJoin<SysDictData>((u, a) => u.Id == a.DictTypeId)
				.Where((u, a) => u.Code == code)
				.WhereIF(Status.HasValue, (u, a) => a.Status == (StatusEnum)Status.Value)
				.OrderBy((u, a) => new { a.OrderNo, a.Code })
				.Select((u, a) => a).ToListAsync();
		}

		public async Task<List<SysDictType>> GetList(string Code, string Name, int pageNumber, int pageSize, RefAsync<int> total)
		{
			var code = !string.IsNullOrEmpty(Code?.Trim());
			var name = !string.IsNullOrEmpty(Name?.Trim());
			var queryable = await _sysDictTypeRepository.AsQueryable();

			if (queryable == null)
			{
				total = 0;
				return null;
			}

			return await queryable
				.WhereIF(code, u => u.Code.Contains(Code))
				.WhereIF(name, u => u.Name.Contains(Name))
				.OrderBy(u => new { u.OrderNo, u.Code })
				.ToPageListAsync(pageNumber, pageSize, total);
		}

		public async Task<List<SysDictType>> GetList()
		{
			var queryable = await _sysDictTypeRepository.AsQueryable();
			return await queryable.OrderBy(u => new { u.OrderNo, u.Code }).ToListAsync();
		}

		public async Task<List<SysDictData>> GetFirstAsync(string Code)
		{
			var dictType = await _sysDictTypeRepository.GetFirstAsync(u => u.Code == Code);
			if (dictType == null)
				throw new UserFriendlyException(RemarkAttribute.GetEnumRemark(ErrorCodeEnum.D3000));
			return await _sysDictDataManager.GetDictDataListByDictTypeId(dictType.Id);
		}

		public async Task<bool> AddDictType(SysDictType input)
		{
			var isExist = await _sysDictTypeRepository.IsAnyAsync(u => u.Code == input.Code);
			if (isExist)
				throw new UserFriendlyException(RemarkAttribute.GetEnumRemark(ErrorCodeEnum.D3001));

			return await _sysDictTypeRepository.InsertAsync(input);
		}

		public async Task UpdateDictType(SysDictType input)
		{
			var isExist = await _sysDictTypeRepository.IsAnyAsync(u => u.Id == input.Id);
			if (!isExist)
				throw new UserFriendlyException(RemarkAttribute.GetEnumRemark(ErrorCodeEnum.D3000));

			isExist = await _sysDictTypeRepository.IsAnyAsync(u => u.Code == input.Code && u.Id != input.Id);
			if (isExist)
				throw new UserFriendlyException(RemarkAttribute.GetEnumRemark(ErrorCodeEnum.D3001));

			await _sysDictTypeRepository.UpdateAsync(input);
		}

		public async Task DeleteDictType(long Id)
		{
			var dictType = await _sysDictTypeRepository.GetFirstAsync(u => u.Id == Id);
			if (dictType == null)
				throw new UserFriendlyException(RemarkAttribute.GetEnumRemark(ErrorCodeEnum.D3000));

			//删除字典值
			await _sysDictTypeRepository.DeleteAsync(dictType);
			await _sysDictDataManager.DeleteDictDataFromDictTypeId(Id);
		}

		public async Task<SysDictType> GetDetail(long Id)
		{
			return await _sysDictTypeRepository.GetFirstAsync(u => u.Id == Id);
		}

		public async Task SetStatus(long Id, StatusEnum Status)
		{
			var dictType = await _sysDictTypeRepository.GetFirstAsync(u => u.Id == Id);
			if (dictType == null)
				throw new UserFriendlyException(RemarkAttribute.GetEnumRemark(ErrorCodeEnum.D3000));

			if (!System.Enum.IsDefined(typeof(StatusEnum), Status))
				throw new UserFriendlyException(RemarkAttribute.GetEnumRemark(ErrorCodeEnum.D3005));

			dictType.Status = Status;
			await _sysDictTypeRepository.UpdateAsync(dictType);
		}

		public async Task<List<SysDictType>> GetAllDictList()
		{
			var queryable = await _sysDictTypeRepository.AsQueryable();
			return await queryable.Includes(u => u.Children).ToListAsync();
		}
	}
}
